package cn.thoughtworks.school.pactise.diary.adapters.outbound.persistence.practiseDiary;

import cn.thoughtworks.school.pactise.diary.domain.context.practiseDiaryContext.practiseDiary.PractiseDiary;
import cn.thoughtworks.school.pactise.diary.domain.context.practiseDiaryContext.practiseDiary.PractiseDiaryRepository;
import org.springframework.data.domain.Pageable;
import org.springframework.stereotype.Repository;

import javax.persistence.EntityNotFoundException;
import javax.persistence.Tuple;
import java.util.Date;
import java.util.List;
import java.util.stream.Collectors;

@Repository
public class PractiseDiaryRepositoryImpl implements PractiseDiaryRepository {
    final PractiseDiaryRepositoryJpaVendor repositoryJpaVendor;

    public PractiseDiaryRepositoryImpl(PractiseDiaryRepositoryJpaVendor repositoryJpaVendor) {
        this.repositoryJpaVendor = repositoryJpaVendor;
    }

    @Override
    public List<PractiseDiary> findByAuthorId(Long authorId, Pageable pageable) {
        return repositoryJpaVendor.findByAuthorId(authorId, pageable).stream().map(PractiseDiaryPO::toDomain).collect(Collectors.toList());
    }

    @Override
    public List<PractiseDiary> findByAuthorIdOrderByDateDesc(Long authorId) {
        return repositoryJpaVendor.findByAuthorIdOrderByDateDesc(authorId).stream().map(PractiseDiaryPO::toDomain).collect(Collectors.toList());
    }

    @Override
    public List<PractiseDiary> findAllByIdIn(List<Long> ids) {
        return repositoryJpaVendor.findAllByIdIn(ids).stream().map(PractiseDiaryPO::toDomain).collect(Collectors.toList());
    }

    @Override
    public List<PractiseDiary> findByAuthorIdAndDateBetween(Long authorId, Date startDate, Date endDate) {
        return repositoryJpaVendor.findByAuthorIdAndDateBetween(authorId, startDate, endDate).stream().map(PractiseDiaryPO::toDomain).collect(Collectors.toList());
    }

    @Override
    public List<Tuple> getMonthlyCountByAuthorIdAndYearBetween(Long authorId, Date startYear, Date endYear) {
        return repositoryJpaVendor.getMonthlyCountByAuthorIdAndYearBetween(authorId, startYear, endYear);
    }

    @Override
    public PractiseDiary save(PractiseDiary practiseDiary) {
        return repositoryJpaVendor.save(PractiseDiaryPO.of(practiseDiary)).toDomain();
    }

    @Override
    public boolean existsById(long id) {
        return repositoryJpaVendor.existsById(id);
    }

    @Override
    public void deleteById(long id) {
        repositoryJpaVendor.deleteById(id);
    }

    @Override
    public PractiseDiary findById(long id) {
        return repositoryJpaVendor.findById(id).map(PractiseDiaryPO::toDomain)
            .orElseThrow(()->new EntityNotFoundException("practise diary entity is not found " + id));
    }
}
